import React, { useEffect, useState } from 'react';
import { Box, ListButton, Pill, SecondaryButton, Text, ThemeColorType } from '@nova-hf/ui';
import { IconType } from '@nova-hf/ui/umd/ts/src/icon-library/iconMap';
import { MainColorType } from '@nova-hf/ui/umd/ts/src/styles/vars.css';
import Authentication from 'beta/store/authentication';
import { formatDate } from 'beta/utils/helpers';
import { useTranslation } from 'beta/utils/i18n';
import { inject, observer } from 'mobx-react';
import { useRouter } from 'next/router';
import {
  PayerChangeRequestStatus,
  useContractPayerChangeRequestsFromQuery,
  useContractPayerChangeRequestsToQuery,
  useCustomerNameLazyQuery,
} from 'typings/graphql';

import { SectionHeader } from '../../../thjonustur/[serviceId]/comoponents/SectionHeader';

import ContractService from './ContractService';

type StatusInfo = {
  color: ThemeColorType;
  icon: IconType;
  text: string;
};

type ContractRequestsContainerProps = {
  authentication?: Authentication;
};

const ContractPayerChangeRequestsContainer = ({
  authentication,
}: ContractRequestsContainerProps) => {
  const { t } = useTranslation('containers');
  const router = useRouter();
  const isStaff = authentication?.isStaff;
  const contractId = typeof router?.query?.contractId === 'string' ? router?.query?.contractId : '';
  const [showRequests, setShowRequests] = useState(true);
  const [customerNames, setCustomerNames] = useState<{ [key: string]: string }>({});
  const [nationalIds, setCustomerNationalIds] = useState<{ [key: string]: string }>({});

  const {
    data: fromData,
    loading: fromLoading,
    error: fromError,
  } = useContractPayerChangeRequestsFromQuery({
    variables: {
      input: {
        id: contractId,
      },
    },
  });

  const {
    data: toData,
    loading: toLoading,
    error: toError,
  } = useContractPayerChangeRequestsToQuery({
    variables: {
      input: {
        id: contractId,
      },
    },
  });

  const payerRequestsFrom = fromData?.contractPayerChangeRequestsFrom;
  const payerRequestsTo = toData?.contractPayerChangeRequestsTo;

  const getStatus = (status: string): StatusInfo | undefined => {
    if (status === PayerChangeRequestStatus.Cancelled) {
      return {
        color: 'warning',
        icon: 'close',
        text: t('contractRequestsContainer.status.cancelled'),
      };
    }
    if (status === PayerChangeRequestStatus.Processed) {
      return {
        color: 'success',
        icon: 'checkMark',
        text: t('contractRequestsContainer.status.processed'),
      };
    }
    if (status === PayerChangeRequestStatus.Pending) {
      return {
        color: 'yellow',
        icon: 'return',
        text: t('contractRequestsContainer.status.pending'),
      };
    }
    if (status === PayerChangeRequestStatus.Unknown) {
      return {
        color: 'grey400',
        icon: 'questionMark',
        text: t('contractRequestsContainer.status.unknown'),
      };
    }

    return undefined;
  };

  const [
    getCustomerNameQuery,
    { data: customerNameData, loading: customerNameLoading, error: customerNameError },
  ] = useCustomerNameLazyQuery();

  useEffect(() => {
    if (customerNameData && !customerNameLoading && !customerNameError) {
      const name = customerNameData?.customer?.name || 'Fannst ekki';
      const nationalId = customerNameData?.customer?.nationalId || '';
      const id = customerNameData?.customer?.id;
      if (id) {
        setCustomerNames((prev) => ({ ...prev, [id]: name }));
        setCustomerNationalIds((prev) => ({ ...prev, [id]: nationalId }));
      }
    }
  }, [customerNameData, customerNameLoading, customerNameError]);

  const fetchCustomerName = (id: string) => {
    getCustomerNameQuery({ variables: { input: { id } } });
  };

  useEffect(() => {
    const fetchNames = () => {
      const ids = [
        ...new Set(
          [...(payerRequestsFrom || []), ...(payerRequestsTo || [])]
            .flatMap((req) => [req?.newContractPayerId, req?.originContractPayerId])
            .filter((id) => id),
        ),
      ];

      ids.forEach((id) => {
        if (id && !customerNames[id]) {
          fetchCustomerName(id);
        }
      });
    };

    fetchNames();
  }, [payerRequestsFrom, payerRequestsTo, customerNames]);

  const customerClick = (nationalId: string) => {
    window.open(`/${nationalId}/thjonustur`, '_blank');
  };

  if (
    (!fromData && !toData) ||
    (fromError && toError) ||
    (fromLoading && toLoading) ||
    (!payerRequestsTo?.length && !payerRequestsFrom?.length)
  ) {
    return null;
  }

  return (
    <Box>
      <Box display="flex" flexDirection="column" gap={2}>
        <Box>
          <SectionHeader
            headerTitle={t('contractRequestsContainer.payerChanges')}
            rightActionNode={
              <SecondaryButton
                colorScheme={'purple'}
                icon={showRequests ? 'minus' : 'add'}
                text={
                  showRequests ? t('contractItemsContainer.hide') : t('contractItemsContainer.show')
                }
                onClick={() => setShowRequests(!showRequests)}
              />
            }
          />
        </Box>
        {showRequests && (
          <Box>
            <Box borderBottomStyle="solid" color="black100" borderWidth="2px" paddingBottom={2}>
              <Box display="grid" gridTemplateColumns={7} gap={2} alignItems="center">
                <Text variant="eyebrowSmall">
                  {t('contractRequestsContainer.headers.subscription')}
                </Text>
                <Text variant="eyebrowSmall">
                  {t('contractRequestsContainer.headers.newSubscription')}
                </Text>
                <Text variant="eyebrowSmall">{t('contractRequestsContainer.headers.payer')}</Text>
                <Text variant="eyebrowSmall">
                  {t('contractRequestsContainer.headers.newPayer')}
                </Text>
                <Text variant="eyebrowSmall">{t('contractRequestsContainer.headers.date')}</Text>
                <Text variant="eyebrowSmall">{t('contractRequestsContainer.headers.status')}</Text>
                {isStaff && (
                  <Text variant="eyebrowSmall">
                    {t('contractRequestsContainer.headers.service')}
                  </Text>
                )}
              </Box>
            </Box>
            {payerRequestsFrom?.map((request) => (
              <React.Fragment key={request?.id}>
                <Box display="grid" gridTemplateColumns={7} gap={2} alignItems="center" marginY={2}>
                  <ListButton
                    icon="plus"
                    text={t('contractRequestsContainer.takeALook')}
                    onClick={() => {
                      router.push(
                        `/beta/${request?.originContractPayerId}/askriftir/${request?.originContractId}`,
                      );
                    }}
                  />

                  <ListButton
                    icon="plus"
                    text={t('contractRequestsContainer.takeALook')}
                    onClick={() => {
                      router.push(
                        `/beta/${request?.newContractPayerId}/askriftir/${request?.newContractId}`,
                      );
                    }}
                  />
                  {request?.originContractPayerId && (
                    <Box
                      cursor="pointer"
                      onClick={() => customerClick(nationalIds[request?.originContractPayerId])}
                    >
                      <Text variant="pSmallRegular">
                        {request?.originContractPayerId
                          ? customerNames[request?.originContractPayerId]
                          : t('contractRequestsContainer.notFound')}
                      </Text>
                    </Box>
                  )}
                  {request?.newContractPayerId && (
                    <Box
                      cursor="pointer"
                      onClick={() => customerClick(nationalIds[request?.newContractPayerId])}
                    >
                      <Text variant="pSmallRegular">
                        {request?.newContractPayerId
                          ? customerNames[request?.newContractPayerId]
                          : t('contractRequestsContainer.notFound')}
                      </Text>
                    </Box>
                  )}
                  <Text variant="pSmallRegular">
                    {request?.effectiveDate
                      ? formatDate(request?.effectiveDate, 'dd.MM.yyyy')
                      : t('contractRequestsContainer.notFound')}
                  </Text>
                  <Pill
                    text={getStatus(request?.status ?? '')?.text ?? ''}
                    color={getStatus(request?.status ?? '')?.color as MainColorType}
                    maxWidth="fitContent"
                    icon={{
                      icon: getStatus(request?.status ?? '')?.icon,
                      color: request?.status === 'Pending' ? 'black100' : 'white',
                      size: 16,
                    }}
                  />
                  {isStaff && <ContractService serviceId={request?.affectedServiceIds?.[0]} />}
                </Box>
                <Box
                  borderColor="grey200"
                  borderBottomStyle="solid"
                  borderWidth="1px"
                  marginBottom={2}
                ></Box>
              </React.Fragment>
            ))}
            {payerRequestsTo?.map((request) => (
              <React.Fragment key={request?.id}>
                <Box display="grid" gridTemplateColumns={7} gap={2} alignItems="center" marginY={2}>
                  <ListButton
                    icon="plus"
                    text={t('contractRequestsContainer.takeALook')}
                    onClick={() => {
                      router.push(
                        `/beta/${request?.originContractPayerId}/askriftir/${request?.originContractId}`,
                      );
                    }}
                  />
                  <ListButton
                    icon="plus"
                    text={t('contractRequestsContainer.takeALook')}
                    onClick={() => {
                      router.push(
                        `/beta/${request?.newContractPayerId}/askriftir/${request?.newContractId}`,
                      );
                    }}
                  />
                  {request?.originContractPayerId && (
                    <Box
                      cursor="pointer"
                      onClick={() => customerClick(nationalIds[request?.originContractPayerId])}
                    >
                      <Text variant="pSmallRegular">
                        {request?.originContractPayerId
                          ? customerNames[request?.originContractPayerId]
                          : t('contractRequestsContainer.notFound')}
                      </Text>
                    </Box>
                  )}
                  {request?.newContractPayerId && (
                    <Box
                      cursor="pointer"
                      onClick={() => customerClick(nationalIds[request?.newContractPayerId])}
                    >
                      <Text variant="pSmallRegular">
                        {request?.newContractPayerId
                          ? customerNames[request?.newContractPayerId]
                          : t('contractRequestsContainer.notFound')}
                      </Text>
                    </Box>
                  )}
                  <Text variant="pSmallRegular">
                    {request?.effectiveDate
                      ? formatDate(request?.effectiveDate, 'dd.MM.yyyy')
                      : t('contractRequestsContainer.notFound')}
                  </Text>
                  <Pill
                    text={getStatus(request?.status ?? '')?.text ?? ''}
                    color={getStatus(request?.status ?? '')?.color as MainColorType}
                    maxWidth="fitContent"
                    icon={{
                      icon: getStatus(request?.status ?? '')?.icon,
                      color: request?.status === 'Pending' ? 'black100' : 'white',
                      size: 16,
                    }}
                  />
                  {isStaff && <ContractService serviceId={request?.affectedServiceIds?.[0]} />}
                </Box>
                <Box
                  borderColor="grey200"
                  borderBottomStyle="solid"
                  borderWidth="1px"
                  marginBottom={2}
                ></Box>
              </React.Fragment>
            ))}
          </Box>
        )}
      </Box>
    </Box>
  );
};

export default inject('ui', 'authentication')(observer(ContractPayerChangeRequestsContainer));
